/**
 * Application Application.java
 */

package CCT220_Trabalho06_13106;


import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;


/**
 * <div style="border-style:double;">
 * Project: CCT220
 * </br>Package: CCT220_Trabalho06_13106
 * </br>Class: Application
 * </br>Created by marcel
 * </br>Description: Classe qe monta a interface de uma calculadora e avalia os
 * resultados
 * </div>
 * 
 * @author marcel
 * @author 13106
 * 
 */
public class Application {

	/**
	 * JTextField jtfResultado
	 */
	private JTextField  jtfResultado;

	/**
	 * JPanel jpButtons
	 */
	private JPanel      jpButtons;

	/**
	 * JButton[][] jbtns
	 */
	private JButton[][] jbtns;

	/**
	 * JButton jbReset
	 */
	private JButton     jbReset;

	/**
	 * String expression
	 */
	private String      expression = "";


	/**
	 * <div style="border-style:double;">
	 * Constructor for
	 * </br>CCT220_Trabalho06_13106::Application
	 * </br>LastChange: 05/11/2011 10:08:22 by marcel
	 * </br>Description: inicia a interface grafica
	 * </div>
	 * 
	 */
	public Application() {

		JFrame jf = new JFrame("Marcel M. Grilo - 13106");
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setSize(300, 250);
		jf.setLayout(new BorderLayout(5, 5));
		this.startComponents();
		jf.add(jtfResultado, BorderLayout.NORTH);
		jf.add(jpButtons, BorderLayout.CENTER);
		jf.add(jbReset, BorderLayout.SOUTH);

		jf.setVisible(true);

	}


	/**
	 * <div style="border-style:double;">
	 * Metho:CCT220_Trabalho06_13106::Application::startComponents
	 * </br>Last Change: 05/11/2011 10:09:09 by marcel
	 * </br>Description: Inicializa os componentes para serem inseridos na
	 * interface grafica
	 * </div>
	 * 
	 */
	private void startComponents() {

		jbtns = new JButton[4][5];
		jbtns[0][0] = new JButton("7");
		jbtns[0][1] = new JButton("8");
		jbtns[0][2] = new JButton("9");
		jbtns[0][3] = new JButton("/");
		jbtns[0][4] = new JButton("(");

		jbtns[1][0] = new JButton("4");
		jbtns[1][1] = new JButton("5");
		jbtns[1][2] = new JButton("6");
		jbtns[1][3] = new JButton("*");
		jbtns[1][4] = new JButton(")");

		jbtns[2][0] = new JButton("1");
		jbtns[2][1] = new JButton("2");
		jbtns[2][2] = new JButton("3");
		jbtns[2][3] = new JButton("-");
		jbtns[2][4] = new JButton("^");

		jbtns[3][0] = new JButton("<-");
		jbtns[3][1] = new JButton(".");
		jbtns[3][2] = new JButton("0");
		jbtns[3][3] = new JButton("+");
		jbtns[3][4] = new JButton("=");

		this.addButtonListenners();

		jtfResultado = new JTextField();
		jtfResultado.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {

			}


			@Override
			public void keyReleased(KeyEvent e) {

				String s = "" + e.getKeyChar();
				if (("0123456789.+-*/\\^()").contains(s)
				        || e.getKeyCode() == KeyEvent.VK_BACK_SPACE
				        || e.getKeyCode() == KeyEvent.VK_DELETE
				        || e.getKeyCode() == KeyEvent.VK_SHIFT) {
					for (JButton[] jbtn : jbtns) {
						for (int j = 0; j < jbtns[0].length; j++) {
							if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE
							        || e.getKeyCode() == KeyEvent.VK_DELETE) {
								expression = ((JTextField) e.getComponent())
								        .getText();
							}
							if (jbtn[j].getText().equals(s)) {
								jbtn[j].doClick();

							}
						}
					}
				} else {
					if (jtfResultado.getText().length() > 0) {
						String str = jtfResultado.getText();
						for (int i = 0; i < str.length(); i++) {
							String c = String.valueOf(str.charAt(i));
							if (!("0123456789.+-*/\\^()").contains(c)) {
								str = str.replace(c, "");
							}
						}
						jtfResultado.setText(str);

					}
				}

			}


			@Override
			public void keyPressed(KeyEvent e) {

			}
		});

		jpButtons = new JPanel(new GridLayout(0, 5, 5, 5));

		for (JButton[] jbtn : jbtns) {
			for (int j = 0; j < jbtns[0].length; j++) {
				jpButtons.add(jbtn[j]);
			}
		}

		jbReset = new JButton("Reset");
		jbReset.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				jtfResultado.setText("");
				expression = "";

			}
		});
	}


	/**
	 * <div style="border-style:double;">
	 * Metho:CCT220_Trabalho06_13106::Application::addButtonListenners
	 * </br>Last Change: 05/11/2011 10:10:56 by marcel
	 * </br>Description: Metodo responsavel por adicionar os devidos listeners
	 * nos botoes
	 * </div>
	 * 
	 */
	private void addButtonListenners() {

		jbtns[0][0].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "7";
				jtfResultado.setText(expression);

			}
		});
		jbtns[0][1].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "8";
				jtfResultado.setText(expression);
			}
		});
		jbtns[0][2].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "9";
				jtfResultado.setText(expression);
			}
		});
		jbtns[0][3].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "/";
				jtfResultado.setText(expression);
			}
		});
		jbtns[0][4].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "(";
				jtfResultado.setText(expression);
			}
		});

		jbtns[1][0].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "4";
				jtfResultado.setText(expression);
			}
		});
		jbtns[1][1].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "5";
				jtfResultado.setText(expression);
			}
		});
		jbtns[1][2].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "6";
				jtfResultado.setText(expression);
			}
		});
		jbtns[1][3].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "*";
				jtfResultado.setText(expression);
			}
		});
		jbtns[1][4].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += ")";
				jtfResultado.setText(expression);
			}
		});

		jbtns[2][0].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "1";
				jtfResultado.setText(expression);
			}
		});
		jbtns[2][1].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "2";
				jtfResultado.setText(expression);
			}
		});
		jbtns[2][2].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "3";
				jtfResultado.setText(expression);
			}
		});
		jbtns[2][3].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "-";
				jtfResultado.setText(expression);
			}
		});
		jbtns[2][4].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "^";
				jtfResultado.setText(expression);
			}
		});

		jbtns[3][0].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression = expression.substring(0, expression.length() - 1);
				jtfResultado.setText(expression);
			}
		});
		jbtns[3][1].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += ".";
				jtfResultado.setText(expression);
			}
		});
		jbtns[3][2].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "0";
				jtfResultado.setText(expression);
			}
		});
		jbtns[3][3].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression += "+";
				jtfResultado.setText(expression);
			}
		});
		jbtns[3][4].addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				expression = new ExpressionEval(jtfResultado.getText())
				        .getResult();
				jtfResultado.setText(expression);
			}
		});

	}


	/**
	 * <div style="border-style:double;">
	 * Metho:CCT220_Trabalho06_13106::Application::main
	 * </br>Last Change: 05/11/2011 10:10:28 by marcel
	 * </br>Description: metodo estatico main que inicia a aplicacao
	 * </div>
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		new Application();

	}
}
